 *******************************************************************************
 Copyright 2023 Arm Limited and affiliates.
 SPDX-License-Identifier: Apache-2.0

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 *******************************************************************************
diff --git a/src/cpu/aarch64/acl_thread.cpp b/src/cpu/aarch64/acl_thread.cpp
index d7d83badcb..1a7bcd74ed 100644
--- a/src/cpu/aarch64/acl_thread.cpp
+++ b/src/cpu/aarch64/acl_thread.cpp
@@ -41,14 +41,17 @@ void acl_thread_bind() {
 #endif

 #if DNNL_CPU_THREADING_RUNTIME == DNNL_RUNTIME_THREADPOOL
-void acl_set_custom_scheduler() {
-    static std::once_flag flag_once;
-    // Create threadpool scheduler
-    std::shared_ptr<arm_compute::IScheduler> threadpool_scheduler
-            = std::make_unique<ThreadpoolScheduler>();
+void acl_set_custom_scheduler(int intra_threads = 0) {
+    static thread_local std::once_flag flag_once;
     // set CUSTOM scheduler in ACL
     std::call_once(flag_once,
-            [&]() { arm_compute::Scheduler::set(threadpool_scheduler); });
+            [&]() {
+                    // Create threadpool scheduler
+                    std::shared_ptr<arm_compute::IScheduler> threadpool_scheduler
+                        = std::make_unique<ThreadpoolScheduler>();
+                    threadpool_scheduler->set_num_threads(intra_threads);
+
+                    arm_compute::Scheduler::set(threadpool_scheduler); });
 }

 void acl_set_threadpool_num_threads() {
diff --git a/src/cpu/aarch64/acl_thread.hpp b/src/cpu/aarch64/acl_thread.hpp
index 46dde5eb05..13b3910515 100644
--- a/src/cpu/aarch64/acl_thread.hpp
+++ b/src/cpu/aarch64/acl_thread.hpp
@@ -34,7 +34,7 @@ void acl_thread_bind();

 #if DNNL_CPU_THREADING_RUNTIME == DNNL_RUNTIME_THREADPOOL
 // Retrieve threadpool size during primitive execution and set ThreadpoolScheduler num_threads
-void acl_set_custom_scheduler();
+void acl_set_custom_scheduler(int intra_threads);
 void acl_set_threadpool_num_threads();
 #endif

diff --git a/src/cpu/aarch64/acl_threadpool_scheduler.cpp b/src/cpu/aarch64/acl_threadpool_scheduler.cpp
index 418d7f30f9..7eb8a052b0 100644
--- a/src/cpu/aarch64/acl_threadpool_scheduler.cpp
+++ b/src/cpu/aarch64/acl_threadpool_scheduler.cpp
@@ -102,8 +102,6 @@ void ThreadpoolScheduler::schedule_op(ICPPKernel *kernel, const Hints &hints,
 void ThreadpoolScheduler::run_workloads(
         std::vector<arm_compute::IScheduler::Workload> &workloads) {

-    arm_compute::lock_guard<std::mutex> lock(this->_run_workloads_mutex);
-
     const unsigned int num_threads
             = std::min(static_cast<unsigned int>(_num_threads),
                     static_cast<unsigned int>(workloads.size()));
diff --git a/src/cpu/cpu_engine.cpp b/src/cpu/cpu_engine.cpp
index 4ee70a405c..e9211f42e0 100644
--- a/src/cpu/cpu_engine.cpp
+++ b/src/cpu/cpu_engine.cpp
@@ -47,6 +47,7 @@ status_t cpu_engine_t::create_stream(stream_t **stream, unsigned flags) {
 #if DNNL_CPU_RUNTIME == DNNL_RUNTIME_THREADPOOL
 status_t cpu_engine_t::create_stream(stream_t **stream,
         dnnl::threadpool_interop::threadpool_iface *threadpool) {
+    dnnl::impl::cpu::aarch64::acl_thread_utils::acl_set_custom_scheduler(threadpool->get_num_threads());
     return safe_ptr_assign<stream_t>(
             *stream, new cpu_stream_t(this, threadpool));
 }
diff --git a/src/cpu/cpu_engine.hpp b/src/cpu/cpu_engine.hpp
index 7aa077e4ef..2938650963 100644
--- a/src/cpu/cpu_engine.hpp
+++ b/src/cpu/cpu_engine.hpp
@@ -175,11 +175,6 @@ public:
         // dnnl_get_max_threads() == OMP_NUM_THREADS
         dnnl::impl::cpu::aarch64::acl_thread_utils::acl_thread_bind();
 #endif
-
-#if DNNL_CPU_THREADING_RUNTIME == DNNL_RUNTIME_THREADPOOL
-        // Set ACL scheduler for threadpool runtime
-        dnnl::impl::cpu::aarch64::acl_thread_utils::acl_set_custom_scheduler();
-#endif
 #endif
         return status::success;
     };
